// userexits.cpp
// Customizer_Pro
// Protea Customizer Pro / Business Logic for managing user exits
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Please send correspondence to:
//
// theproteaproject@gmail.com
//
#include "pro_customizer.h"

// USER_EXIT_DEFNS Subtransactions
//
//////////////////////////////////////////////////////////////////////////////



//@ SEC 3
//@ CHA User Exit Defns Add
//@ COD UserExitDefnsAdd
//@ TAB USER_EXIT_DEFNS Write
//@ GEN Use UserExitDefnsAdd to add a User Exit Defns record
void UserExitDefnsAdd( XCBuffer* buf, XCTransactionVars* vars ) 
{
	TRANS_INFUNC( UserExitDefnsAdd );

	XCDBStatement* stmt = NULL;
	XCBuffer* temp = NULL;
	XCSQLGen* query = vars->query;

	long last_number = 0;

	//@ Determine the next available user exit field number
	temp = App->CreateBuffer( FMT_USER_EXIT_DEFNS );
	try {
		XCOrder ord;
		bool found = false;

		query->MakeSELECT( temp );
		query->AddWHERE( 1, buf->GetField( FLD_APPL_NBR ) );
		query->AddORDERBY( FLD_USER_EXIT_NUMBER, &ord );
		stmt = vars->dbtxn->ExecuteSQL( query );
		while ( !found && !stmt->Eof() )
		{
			long value = temp->GetField( FLD_USER_EXIT_NUMBER )->GetLong( true );
			if ( value != last_number + 1 )
			{
				// we found a blank space
				found = true;
				last_number++;
			}
			else
			{
				last_number = value;
				stmt->MoveNext();
			};
		};

		// Cleanup now
		App->CleanupObjects( 2, &temp, &stmt );

		if (!found)
			last_number++;
		buf->GetField( FLD_USER_EXIT_NUMBER )->SetLong( last_number );

	} catch( ... ) {
		App->CleanupObjects( 2, &temp, &stmt );
		throw;
	};

	//@ Add the record
	query->MakeFull( SQL_STMT_INSERT, buf );
	vars->dbtxn->ExecuteSQL( query, SQL_NO_RESULT );

	TRANS_OUTFUNC();
};




//@ SEC 3
//@ CHA User Exit Defns Delete
//@ COD UserExitDefnsDelete
//@ TAB USER_EXIT_DEFNS Write
//@ GEN Use to delete User Exit Defns records
void UserExitDefnsDelete( XCBuffer* buf, XCTransactionVars* vars ) 
{
	TRANS_INFUNC( UserExitDefnsDelete );

	XCSQLGen* query = vars->query;

	//@ Delete the record
	query->MakeFull( SQL_STMT_DELETE, buf );
	vars->dbtxn->ExecuteSQL( query, SQL_NO_RESULT );

	TRANS_OUTFUNC();
};





// USER_EXIT_DEFNS Transactions
//
//////////////////////////////////////////////////////////////////////////////

//@ SEC 2
//@ CHA Add User Exit
//@ COD AddUserExit
//@ NUM 38
//@ CRI USER_EXIT_NAME
//@ CRI TRANS_CODE
//@ GEN Add User Exit will add a user exit for an application
TRANSACTION_CODE( AddUserExit )
{
	XCBuffer* buf = NULL;

	//@ GRS Start the transaction
	START_TXN( AddUserExit );

		//@ If critical fields are blank, then
		//@ ERR E (1730) (Field Name) cannot be blank
		if ( txnvars.buffer->GetField( FLD_USER_EXIT_NAME )->IsBlank() )
			txnvars.Errors->Add( ERR_IS_BLANK, SEV_ERROR, FLD_USER_EXIT_NAME, 1, txnvars.buffer->GetField( FLD_USER_EXIT_NAME ) );
		if ( txnvars.buffer->GetField( FLD_TRANS_CODE )->IsBlank() )
			txnvars.Errors->Add( ERR_IS_BLANK, SEV_ERROR, FLD_TRANS_CODE, 1, txnvars.buffer->GetField( FLD_TRANS_CODE ) );
		txnvars.Errors->Check();

		//@ Create transaction buffer
		buf = App->CreateBuffer( FMT_USER_EXIT_DEFNS );

		//@ Move screen info to transaction buffer
		buf->MoveCorresponding( txnvars.buffer, txnvars.Errors );
		txnvars.Errors->Check();

		START_DB_TXN();

			//@ SUB SystemValuesVerify to verify that system value can be added
			UserExitDefnsVerify( buf, VERIFY_ADD, &txnvars );

			//@ Check for errors
			txnvars.Errors->Check();

			//@ SUB SystemValuesAdd to add the new system value
			UserExitDefnsAdd( buf, &txnvars );

			LOG_TRANSACTION();

		END_DB_TXN();

		txnvars.buffer->MoveCorresponding( buf, txnvars.Errors );
		App->TransResponse( txnvars.result, txnvars.buffer, TRANS_HEADER_TYPE );

	CLEANUP_TXN();
		App->CleanupObjects( 1, &buf );
	END_TXN();
	//@ GRE End the transaction
};


//@ CHA Delete User Exit
//@ COD DeleteUserExit
//@ NUM 39
//@ CRI FIELD_NAME
//@ GEN Delete User Exit will delete a User Exit record
TRANSACTION_CODE( DeleteUserExit ) 
{
	XCBuffer* buf = NULL;

	//@ GRS Start the transaction
	START_TXN( DeleteUserExit );

		//@ Create transaction buffer
		buf = App->CreateBuffer( FMT_USER_EXIT_DEFNS );

		//@ Move screen info to transaction buffer
		buf->MoveCorresponding( txnvars.buffer, txnvars.Errors );
		txnvars.Errors->Check();

		START_DB_TXN();
			//@ SUB SystemValuesVerify to verify that record can be deleted
			UserExitDefnsVerify( buf, VERIFY_DELETE, &txnvars );
			txnvars.Errors->Check();

			//@ SUB SystemValuesDelete to delete the record.
			UserExitDefnsDelete( buf, &txnvars );

			LOG_TRANSACTION();

		END_DB_TXN();

	CLEANUP_TXN();
		App->CleanupObjects( 1, &buf );
	END_TXN();
	//@ GRE End the transaction
};

